package com.hzw.service.impl;

import com.hzw.bean.*;
import com.hzw.dao.*;
import com.hzw.dto.ArticleCondition;
import com.hzw.dto.ArticleParam;
import com.hzw.dto.ArticleResponse;
import com.hzw.service.ArticleService;
import com.hzw.utils.ObjectUtils;
import com.hzw.utils.UUIDUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2019/3/14.
 */
@Service
public class ArticleServiceImpl implements ArticleService{
    @Resource
    private ArticleMapper articleMapper;
    @Resource
    private ArticleDetailMapper articleDetailMapper;
    @Resource
    private ArticleCategoryRelationMapper articleCategoryRelationMapper;
    @Resource
    private ArticleTagRelationMapper articleTagRelationMapper;
    @Resource
    private ArticleCommentMapper articleCommentMapper;
    @Resource
    private ArticleCategoryMapper articleCategoryMapper;
    @Resource
    private ArticleTagMapper articleTagMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private MessageMapper messageMapper;
    @Resource
    private LikeRelationMapper likeRelationMapper;

    /**
     * 新增博文，同时新增博文详情
     * @param articleParam
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addArticle(ArticleParam articleParam) {
        Article article = articleParam.getArticle();
        List<String> categoryIdList = articleParam.getCategoryIdList();
        List<String> tagIdList = articleParam.getTagIdList();

        //插入新增文章
        String articleId = UUIDUtils.getUUID();
        article.setId(articleId);
        articleMapper.insertSelective(article);

        //修改用户文章数+1
        userMapper.updateArticleNum(articleParam.getArticle().getUserId(),1);

        //创建并插入文章细节对象
        ArticleDetail articleDetail = new ArticleDetail();
        String articleDetailId = UUIDUtils.getUUID();
        articleDetail.setId(articleDetailId);
        articleDetail.setArticleId(articleId);
        articleDetailMapper.insertSelective(articleDetail);

        //将用户选择的文章分类插入文章分类关系表
        if(!ObjectUtils.isNullOrEmpty(categoryIdList) && categoryIdList.size() > 0){
            for (String s : categoryIdList) {
                ArticleCategoryRelation articleCategoryRelation = new ArticleCategoryRelation();
                articleCategoryRelation.setId(UUIDUtils.getUUID());
                articleCategoryRelation.setArticleId(articleId);
                articleCategoryRelation.setCategoryId(s);
                articleCategoryRelationMapper.insertSelective(articleCategoryRelation);
            }
        }

        //将用户选择的文章标签插入文章标签关系表
        if(!ObjectUtils.isNullOrEmpty(tagIdList) && tagIdList.size() > 0){
            for (String s : tagIdList) {
                ArticleTagRelation articleTagRelation = new ArticleTagRelation();
                articleTagRelation.setId(UUIDUtils.getUUID());
                articleTagRelation.setArticleId(articleId);
                articleTagRelation.setTagId(s);
                articleTagRelationMapper.insertSelective(articleTagRelation);
            }
        }

        //增加用户的活跃度 +5
        String userId = articleParam.getArticle().getUserId();
        userMapper.addActivityLevel(userId,5);

        //判断活跃度+1后是否达到100，若达到则修改会员标志位
        User user = userMapper.selectUserById(userId);
        if(user.getActivityLevel() >= 100 && user.getMemberFlag() == 0){
            user.setMemberFlag(1);
            userMapper.updateByPrimaryKeySelective(user);
        }
    }

    /**
     * 删除博文：软删除，把del_flag设为1
     * 同时把文章关联的数据表数据也软删除
     * @param articleId
     * @return 返回受影响(或匹配上但没修改)的行数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteArticleById(String articleId) {
        int count = 0;

        //修改用户文章数-1
        Article article = articleMapper.selectArticleById(articleId);
        userMapper.updateArticleNum(article.getUserId(),-1);

        count = articleMapper.deleteArticleById(articleId); //软删除文章表

        articleDetailMapper.deleteArticleDetail(articleId);//软删除文章细节表
        articleCategoryRelationMapper.deleteArticleCategoryRelation(articleId);  //软删除文章分类关系表
        articleTagRelationMapper.deleteArticleTagRelation(articleId);  //软删除文章标签关系表
        articleCommentMapper.deleteArticleComment(articleId);  //软删除文章评论表
        return count;
    }

    /**
     * 更新文章表以及文章相关数据表：只更新非空字段
     * @param articleParam
     * @return 返回受影响(或匹配上但没修改)的行数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateArticleById(ArticleParam articleParam) {
        Article article = articleParam.getArticle();
        List<String> categoryIdList = articleParam.getCategoryIdList();
        List<String> tagIdList = articleParam.getTagIdList();
        String articleId = article.getId();
        int count = 0;
        //更新文章
        count = articleMapper.updateByPrimaryKeySelective(article);

        //更新文章分类(先软删分类，再新增分类)
        articleCategoryRelationMapper.deleteArticleCategoryRelation(articleId);  //软删除文章分类关系表
        //将用户选择的文章分类插入文章分类关系表
        if(!ObjectUtils.isNullOrEmpty(categoryIdList) && categoryIdList.size() > 0){
            for (String s : categoryIdList) {
                ArticleCategoryRelation articleCategoryRelation = new ArticleCategoryRelation();
                articleCategoryRelation.setId(UUIDUtils.getUUID());
                articleCategoryRelation.setArticleId(articleId);
                articleCategoryRelation.setCategoryId(s);
                articleCategoryRelationMapper.insertSelective(articleCategoryRelation);
            }
        }

        articleTagRelationMapper.deleteArticleTagRelation(articleId);  //软删除文章标签关系表
        //将用户选择的文章标签插入文章标签关系表
        if(!ObjectUtils.isNullOrEmpty(tagIdList) && tagIdList.size() > 0){
            for (String s : tagIdList) {
                ArticleTagRelation articleTagRelation = new ArticleTagRelation();
                articleTagRelation.setId(UUIDUtils.getUUID());
                articleTagRelation.setArticleId(articleId);
                articleTagRelation.setTagId(s);
                articleTagRelationMapper.insertSelective(articleTagRelation);
            }
        }
        return count;
    }

    /**
     * 根据articleId查找博文
     * @param articleId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ArticleResponse selectArticleById(String articleId) {
        ArticleResponse articleResponse = new ArticleResponse();
        //根据Id查找文章
        Article article = articleMapper.selectArticleById(articleId);

        //将作者名放入article
        User user = userMapper.selectUserById(article.getAuthorId());
        article.setAuthorName(user.getUserName());

        //根据Id查找文章细节
        ArticleDetail articleDetail = articleDetailMapper.selectArticleDetailByArticleId(articleId);
        //根据Id查找文章分类
        List<ArticleCategory> articleCategoryList = articleCategoryMapper.selectArticleCategoryByArticleId(articleId);
        //根据Id查找文章标签
        List<ArticleTag> articleTagList = articleTagMapper.selectArticleTagByArticleId(articleId);

        //修改文章浏览数+1
        articleDetailMapper.updateReadNum(articleId,1);

        //把数据装入articleResponse
        articleResponse.setArticle(article);
        articleResponse.setArticleDetail(articleDetail);
        articleResponse.setArticleCategoryList(articleCategoryList);
        articleResponse.setArticleTagList(articleTagList);
//        articleResponse.setArticleCommentList(articleCommentList);

        return articleResponse;
    }

    /**
     * 根据userId查找属于该用户的博文
     * @param userId
     * @return
     */
//    @Override
//    public List<Article> selectArticleByUserId(String userId) {
//        return articleMapper.selectArticleByUserIds(userId);
//    }

    /**
     * 根据条件查找博文，三种场景 1、大厅(所有博文) 2、个人首页（自己和好友的博文） 3、个人博文
     * @param articleCondition
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<ArticleResponse> selectArticleByCondition(ArticleCondition articleCondition) {
        List<ArticleResponse> articleResponseList = new ArrayList<ArticleResponse>();

        //查找出符合条件的博文
        List<Article> articleList = articleMapper.selectArticleByCondition(articleCondition);

        //遍历博文列表，找出博文详情（点赞数、评价数那些需要显示在博客列表上）
        if(!ObjectUtils.isNullOrEmpty(articleList)){
            for (Article article : articleList) {
                ArticleResponse articleResponse = new ArticleResponse();
                String articleId = article.getId();
                //减小列表的数据量，将text设为null
                article.setText(null);
                //根据Id查找文章细节
                ArticleDetail articleDetail = articleDetailMapper.selectArticleDetailByArticleId(articleId);
                //根据Id查找文章标签
                List<ArticleTag> articleTagList = articleTagMapper.selectArticleTagByArticleId(articleId);
                //根据Id查找文章分类
                List<ArticleCategory> articleCategoryList = articleCategoryMapper.selectArticleCategoryByArticleId(articleId);

                //将作者名放入article
                User user = userMapper.selectUserById(article.getAuthorId());
                article.setAuthorName(user.getUserName());

                //把数据装入articleResponse
                articleResponse.setArticle(article);
                articleResponse.setArticleDetail(articleDetail);
                articleResponse.setArticleTagList(articleTagList);
                articleResponse.setArticleCategoryList(articleCategoryList);

                //把articleResponse装入列表
                articleResponseList.add(articleResponse);
            }
        }
        return articleResponseList;
    }

    @Override
    public List<ArticleResponse> selectChargeFull() {
        List<ArticleResponse> articleResponseList = new ArrayList<ArticleResponse>();

        //查找出被举报数大于等于30的博文
        List<Article> articleList = articleMapper.selectChargeFull();

        //遍历博文列表，找出博文详情（点赞数、评价数那些需要显示在博客列表上）
        if(!ObjectUtils.isNullOrEmpty(articleList)){
            for (Article article : articleList) {
                ArticleResponse articleResponse = new ArticleResponse();
                String articleId = article.getId();
                //减小列表的数据量，将text设为null
                article.setText(null);
                //根据Id查找文章细节
                ArticleDetail articleDetail = articleDetailMapper.selectArticleDetailByArticleId(articleId);
                //根据Id查找文章标签
                List<ArticleTag> articleTagList = articleTagMapper.selectArticleTagByArticleId(articleId);
                //根据Id查找文章分类
                List<ArticleCategory> articleCategoryList = articleCategoryMapper.selectArticleCategoryByArticleId(articleId);


                //把数据装入articleResponse
                articleResponse.setArticle(article);
                articleResponse.setArticleDetail(articleDetail);
                articleResponse.setArticleTagList(articleTagList);
                articleResponse.setArticleCategoryList(articleCategoryList);

                //把articleResponse装入列表
                articleResponseList.add(articleResponse);
            }
        }
        return articleResponseList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<ArticleResponse> selectArticleByKeyWord(String keyWord) {
        List<ArticleResponse> articleResponseList = new ArrayList<ArticleResponse>();

        //查找出符合条件的博文
        List<Article> articleList = articleMapper.selectArticleByKeyWord(keyWord);

        //遍历博文列表，找出每条博文相关的数据
        if(!ObjectUtils.isNullOrEmpty(articleList)){
            for (Article article : articleList) {
                ArticleResponse articleResponse = new ArticleResponse();
                String articleId = article.getId();
                //减小列表的数据量，将text设为null
                article.setText(null);
                //根据Id查找文章细节
                ArticleDetail articleDetail = articleDetailMapper.selectArticleDetailByArticleId(articleId);
                //根据Id查找文章标签
                List<ArticleTag> articleTagList = articleTagMapper.selectArticleTagByArticleId(articleId);
                //根据Id查找文章分类
                List<ArticleCategory> articleCategoryList = articleCategoryMapper.selectArticleCategoryByArticleId(articleId);

                //将作者名放入article
                User user = userMapper.selectUserById(article.getAuthorId());
                article.setAuthorName(user.getUserName());

                //把数据装入articleResponse
                articleResponse.setArticle(article);
                articleResponse.setArticleDetail(articleDetail);
                articleResponse.setArticleTagList(articleTagList);
                articleResponse.setArticleCategoryList(articleCategoryList);
                //articleResponse.setArticleCommentList(articleCommentList);

                //把articleResponse装入列表
                articleResponseList.add(articleResponse);
            }
        }
        return articleResponseList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addLike(String userId, String articleId) {
        //修改文章的点赞数+1
        articleDetailMapper.updateLikeNum(articleId,1);
        //通过userId和articleId查找点赞关系表，若存在则直接修改，不存在则新增
        LikeRelation likeRelation = likeRelationMapper.selectByTwoId(userId,articleId);
        if(likeRelation == null){ //不存在此关系，新建实体类，将点赞关系存入点赞关系表
            likeRelation = new LikeRelation();
            likeRelation.setId(UUIDUtils.getUUID());
            likeRelation.setArticleId(articleId);
            likeRelation.setUserId(userId);
            likeRelation.setLikeFlag(1);
            likeRelationMapper.insertSelective(likeRelation);
        }else { //存在此关系，直接修改likeFlag
            likeRelation.setLikeFlag(1);
            likeRelationMapper.updateByPrimaryKeySelective(likeRelation);
        }

        //修改点赞人活跃度+1
        userMapper.addActivityLevel(userId,1);
        //判断活跃度+1后是否达到100，若达到则修改会员标志位
        User user = userMapper.selectUserById(userId);
        if(user.getActivityLevel() >= 100 && user.getMemberFlag() == 0){
            user.setMemberFlag(1);
            userMapper.updateByPrimaryKeySelective(user);
        }

        //发消息通知被赞用户(作者)
        Message message = new Message();
        String id = UUIDUtils.getUUID();
        Article article = articleMapper.selectArticleById(articleId);//通过articleId获取文章标题和作者Id
        String title = article.getTitle();
        String authorId = article.getUserId();
        String userName = userMapper.selectUserNameById(userId);//根据userId获取点赞人用户名
        message.setId(id);
        message.setUserId(authorId);
        message.setType(0);
        message.setText("用户“" +userName +"”点赞了你的《" + title + "》");
        messageMapper.insertSelective(message);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int cancelLike(String userId, String articleId) {
        //修改点赞关系表
        likeRelationMapper.updateLikeFlag(userId,articleId,0);
        //修改文章的点赞数-1
        int i= articleDetailMapper.updateLikeNum(articleId,-1);
        return i;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void transpondArticle(String transpondUserId,Article article) {
        Article article1 = new Article();//创建Article
        article1.setId(UUIDUtils.getUUID());//重新生成id
        article1.setUserId(transpondUserId);//将转发者Id的值赋给文章的userId
        article1.setAuthorId(article.getAuthorId());//设置作者id
        article1.setTitle(article.getTitle());
        article1.setArticleCoverPath(article.getArticleCoverPath());
        article1.setText(article.getText());
        articleMapper.insertSelective(article1);

        //增加转发用户的文章数
        userMapper.updateArticleNum(transpondUserId,1);

        //增加文章被转发数
        articleDetailMapper.updateTranspondNum(article.getId(),1);

        //发消息通知被赞用户(作者)
        Message message = new Message();
        String id = UUIDUtils.getUUID();
        String title = article.getTitle();
        String authorId = article.getAuthorId();
        String userName = userMapper.selectUserNameById(transpondUserId);//根据userId获取转发人用户名
        message.setId(id);
        message.setUserId(authorId);
        message.setType(2);
        message.setText("用户“" +userName +"”转发了你的《" + title + "》");
        messageMapper.insertSelective(message);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void chargeArticle(String transpondUserId,Article article) {
        //修改文章的举报数
        articleDetailMapper.updateChargeNum(article.getId(),1);

        //发消息通知被举报用户(作者)
        Message message = new Message();
        String id = UUIDUtils.getUUID();
        String title = article.getTitle();
        String authorId = article.getUserId();
        String userName = userMapper.selectUserNameById(transpondUserId);//根据userId获取转发人用户名
        message.setId(id);
        message.setUserId(authorId);
        message.setType(3);
        message.setText("用户“" +userName +"”举报了你的《" + title + "》");
        messageMapper.insertSelective(message);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<ArticleResponse> selectRecommendArticle() {
        List<ArticleResponse> articleResponseList = new ArrayList<ArticleResponse>();

        //查找出推荐文章列表前十条
        List<Article> articleList = articleMapper.selectRecommendArticle();

        //遍历博文列表，找出博文详情（点赞数、评价数那些需要显示在博客列表上）
        if(!ObjectUtils.isNullOrEmpty(articleList)){
            for (Article article : articleList) {
                ArticleResponse articleResponse = new ArticleResponse();
                String articleId = article.getId();
                //减小列表的数据量，将text设为null
                article.setText(null);
                //根据Id查找文章细节
                ArticleDetail articleDetail = articleDetailMapper.selectArticleDetailByArticleId(articleId);
                //根据Id查找文章标签
                List<ArticleTag> articleTagList = articleTagMapper.selectArticleTagByArticleId(articleId);
                //根据Id查找文章分类
                List<ArticleCategory> articleCategoryList = articleCategoryMapper.selectArticleCategoryByArticleId(articleId);

                //把数据装入articleResponse
                articleResponse.setArticle(article);
                articleResponse.setArticleDetail(articleDetail);
                articleResponse.setArticleTagList(articleTagList);
                articleResponse.setArticleCategoryList(articleCategoryList);

                //把articleResponse装入列表
                articleResponseList.add(articleResponse);
            }
        }
        return articleResponseList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteChargeFull(Article article) {
        //软删除文章
        articleMapper.deleteArticleById(article.getId());
        //发消息通知被删博文用户
        Message message = new Message();
        String id = UUIDUtils.getUUID();
        String title = article.getTitle();
        String userId = article.getUserId();
        message.setId(id);
        message.setUserId(userId);
        message.setType(4);
        message.setText("由于被举报过多，系统管理员"  +"删除了你的《" + title + "》");
        messageMapper.insertSelective(message);
        return 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<ArticleResponse> selectNewestArticle() {
        List<ArticleResponse> articleResponseList = new ArrayList<ArticleResponse>();

        //查找出最新的前十条文章
        List<Article> articleList = articleMapper.selectNewestArticle();

        //遍历博文列表，找出博文详情（点赞数、评价数那些需要显示在博客列表上）
        if(!ObjectUtils.isNullOrEmpty(articleList)){
            for (Article article : articleList) {
                ArticleResponse articleResponse = new ArticleResponse();
                String articleId = article.getId();
                //减小列表的数据量，将text设为null
                article.setText(null);
                //根据Id查找文章细节
                ArticleDetail articleDetail = articleDetailMapper.selectArticleDetailByArticleId(articleId);
                //根据Id查找文章标签
                List<ArticleTag> articleTagList = articleTagMapper.selectArticleTagByArticleId(articleId);
                //根据Id查找文章分类
                List<ArticleCategory> articleCategoryList = articleCategoryMapper.selectArticleCategoryByArticleId(articleId);

                //将作者名放入article
                User user = userMapper.selectUserById(article.getAuthorId());
                article.setAuthorName(user.getUserName());

                //把数据装入articleResponse
                articleResponse.setArticle(article);
                articleResponse.setArticleDetail(articleDetail);
                articleResponse.setArticleTagList(articleTagList);
                articleResponse.setArticleCategoryList(articleCategoryList);

                //把articleResponse装入列表
                articleResponseList.add(articleResponse);
            }
        }
        return articleResponseList;
    }

    /**
     * 后台获取推荐列表
     * @param article1
     * @return
     */
    @Override
    public List<ArticleResponse> selectRecommendArticleByCondition(Article article1) {
        List<ArticleResponse> articleResponseList = new ArrayList<ArticleResponse>();

        //查找出符合条件的列表
        List<Article> articleList = articleMapper.selectRecommendArticleByCondition(article1);

        //遍历博文列表，找出博文详情（点赞数、评价数那些需要显示在博客列表上）
        if(!ObjectUtils.isNullOrEmpty(articleList)){
            for (Article article : articleList) {
                ArticleResponse articleResponse = new ArticleResponse();
                String articleId = article.getId();
                //减小列表的数据量，将text设为null
                article.setText(null);
                //根据Id查找文章细节
                ArticleDetail articleDetail = articleDetailMapper.selectArticleDetailByArticleId(articleId);
                //根据Id查找文章标签
                List<ArticleTag> articleTagList = articleTagMapper.selectArticleTagByArticleId(articleId);
                //根据Id查找文章分类
                List<ArticleCategory> articleCategoryList = articleCategoryMapper.selectArticleCategoryByArticleId(articleId);

                //将作者名放入article
                User user = userMapper.selectUserById(article.getAuthorId());
                article.setAuthorName(user.getUserName());

                //把数据装入articleResponse
                articleResponse.setArticle(article);
                articleResponse.setArticleDetail(articleDetail);
                articleResponse.setArticleTagList(articleTagList);
                articleResponse.setArticleCategoryList(articleCategoryList);

                //把articleResponse装入列表
                articleResponseList.add(articleResponse);
            }
        }
        return articleResponseList;
    }

}
